﻿using System.Collections.Generic;
using System.Linq;
using System.Windows;
using ChessKit.Common;
using ChessKit.Ui.ChessPanel;

namespace ChessKit.Ui
{
  public class BoardPanel
  {
    #region ' LocationChanged (routed event) '

    public static readonly RoutedEvent LocationChangedEvent = EventManager.
      RegisterRoutedEvent("LocationChanged", RoutingStrategy.Bubble,
      typeof(RoutedEventHandler), typeof(BoardPanel));

    public static void AddLocationChangedHandler(UIElement uie, RoutedEventHandler handler)
    {
      uie.AddHandler(LocationChangedEvent, handler);
    }
    public static void RemoveLocationChangedHandler(UIElement uie, RoutedEventHandler handler)
    {
      uie.RemoveHandler(LocationChangedEvent, handler);
    }

    private static void RaiseLocationChangedEvent(UIElement target)
    {
      target.RaiseEvent(new DraggingEventArgs(LocationChangedEvent));
    }

    #endregion


    #region ' Location : BoardLocation (Attached Property) '

    public static readonly DependencyProperty LocationProperty = DependencyProperty.
      RegisterAttached("Location", typeof (BoardLocation), typeof (BoardPanel),
                       new FrameworkPropertyMetadata(BoardLocation.Unknown,
                         FrameworkPropertyMetadataOptions.AffectsParentMeasure,
                         OnLocationChanged));

    private static void OnLocationChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
      var oldLocation = (BoardLocation) e.OldValue;
      if (oldLocation == BoardLocation.Unknown) return;

      RaiseLocationChangedEvent((UIElement) d);
    }

    public static BoardLocation GetLocation(DependencyObject obj)
    {
      return (BoardLocation) obj.GetValue(LocationProperty);
    }

    public static void SetLocation(DependencyObject obj, BoardLocation value)
    {
      obj.SetValue(LocationProperty, value);
    }

    #endregion

    #region ' Locations : BoardLocations (Attached Property) '

    public static readonly DependencyProperty LocationsProperty = DependencyProperty.
      RegisterAttached("Locations", typeof (BoardLocations), typeof (BoardPanel),
                       new FrameworkPropertyMetadata(null,
                                                     FrameworkPropertyMetadataOptions.AffectsParentMeasure,
                                                     OnLocationsChanged));

    private static void OnLocationsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
      var oldLocations = (BoardLocations) e.OldValue;
      if (!IsValid(oldLocations)) return;

      RaiseLocationChangedEvent((UIElement)d);
    }

    public static BoardLocations GetLocations(DependencyObject obj)
    {
      return (BoardLocations) obj.GetValue(LocationsProperty);
    }

    public static void SetLocations(DependencyObject obj, BoardLocations value)
    {
      obj.SetValue(LocationsProperty, value);
    }

    private static bool IsValid(BoardLocations locations)
    {
      if (locations == null) return false;
      if (locations.Count < 2) return false;
      return locations.All(l => l != BoardLocation.Unknown);
    }

    #endregion
  }
}
